<?php

namespace yxixia;

use think\Db;
use Payment\Client\Charge;
use Payment\Client\Notify;
use Payment\Client\Query;
use Payment\Client\Transfer;
use Payment\Config;
use think\Log;
class Payment {
    /**
     * 支付方式
     * @param Array $order 订单数据
     * @return boolean false 如果失败|['url'=>支付链接，'iserwm'=>是否二维码，'payname'=>支付名称]
     * **/
    public function pay($order){
        if(empty($order)){
            echo 'no order';
            return false;
        }
        if(empty($order['paymode'])){
             echo 'no paytype';
            return false;
        }
        $method = $order['paymode'];
        $payConfig = Db::name('paymode')->find($method);
        if(empty($payConfig)||$payConfig['enable_i']!=1){
             echo 'paytype closed';
            return false;
        }
        $paymode = $payConfig['classname'];
//        $class = 'app\\pay\\Controller\\pay\\'.$paymode;
//        if(!class_exists($class)){
//             echo 'paytype not open';
//            return false;
//        }
        $payData = [
            'body'    => isset($order['paymode'])?$order['paymode']:'ali web pay',
            'subject'    => isset($order['subject'])?$order['subject']:'优卡',
            'order_no'    => $order['orderid'],
            'timeout_express' => time() + 600,// 表示必须 600s 内付款
            'amount'    => $order['price'],// 单位为元 ,最小为0.01
//            'amount'    => '0.01',
            'return_param' => '123123',//passback_params 会原样返回的数据
            'client_ip' => isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1',// 客户地址
            'goods_type' => '0',//0 虚拟 1实物
            'store_id' => '',//商户门店编号。该参数用于请求参数中以区分各门店，非必传项。
            'product_id' => $order['itemid'],
            // 说明地址：https://doc.open.alipay.com/doc2/detail.htm?treeId=270&articleId=105901&docType=1
            // 建议什么也不填
            'qr_mod' => '',
//            'scene_info' => [
//                'type' => 'Wap',// IOS  Android  Wap  腾讯建议 IOS  ANDROID 采用app支付
//                'wap_url' => 'pay.18yb.com',//自己的 wap 地址
//                'wap_name' => '测试充值',
//            ],
        ];
        $cfg = json_decode($payConfig['payconfig'],true);
        $url = Charge::run($paymode, $cfg, $payData);
        if(empty($url)){
            return false;
        }
        $rs=['url'=>$url,'iserwm'=>$payConfig['is_showewm'],'payname'=>$payConfig['payname']];
        return $rs;
    }
    
    public function notify($method,$order){
        if(empty($order)){
            return true;
        }
        if($order['status']>1){
            return true;
        }
        if(empty($order['paymode'])){
            Log::write('not set paymode',Log::ERROR);
            return false;
        }
        $paymode = $order['paymode'];
        $payConfig = Db::name('paymode')->find($paymode);
        if(empty($payConfig)){
            return true;
        }
        $cfg = json_decode($payConfig['payconfig'],true);
        try {
            $ret = Notify::run($method, $cfg);// 处理回调，内部进行了签名检查
            return $ret;
        } catch (PayException $e) {
            Log::write($e,Log::ERROR);
            return false;
        }
        return false;
    }
    
    public function query($order){
        
        if(empty($order)){
            echo 'no order';
            return false;
        }
        if($order['status']==2){
            return true;
        }
        if(empty($order['paymode'])){
             echo 'no paytype';
            return false;
        }
        
        $data = [
            'out_trade_no' => $order['orderid'],
            'trade_no' => $order['trade_no']//'2017043021001004350200163279',
        ];
        $payConfig = Db::name('paymode')->find($order['paymode']);
        if(empty($payConfig)||$payConfig['enable_i']!=1){
             echo 'paytype closed';
            return false;
        }
        $cfg = json_decode($payConfig['payconfig'],true);
       
        if(strpos($payConfig['classname'],'ali_')===0){
            $method = Config::ALI_CHARGE;
        }elseif(strpos($payConfig['classname'],'wx_')===0){
            $method = Config::WX_CHARGE;
        }else{
            echo 'uknown paytype '.$payConfig['classname'];
            return false;
        }
        try {
            $ret = Query::run($method, $cfg, $data);
            return $ret;
        } catch (PayException $e) {
            echo $e->errorMessage();
            exit;
        }
    }
    
    public function paymode($uid,$filter=''){
        $mbdetect = new \yxixia\Mobile_Detect;
        $ismobile = $mbdetect->isMobile()?1:0;
        $arr = Db::name('paymode')->field('paymode,payname,icon_url,classname,is_mobile')->where(['enable_i'=>1,'is_mobile'=>$ismobile])->select();
        $modeInfos = [];
        $ud = Db::name('user_paymode')->where('userid',$uid)->find();
        if(empty($ud)){
            return $modeInfos;
        }
        $uset = json_decode($ud['paymode'],true);
        $sysset = json_decode($ud['payprofit'],true);
        foreach ($arr as $paymode){
            $key = $paymode['paymode'];
            if(isset($uset[$key])&&isset($sysset[$key])){
                $modeInfos[$key] =  $paymode;
            }
        }
        if(empty($filter)){
            return $modeInfos;
        }
        $paymodes = [];
        $modes = explode(';', $filter);
        foreach ($modes as $modename){
            if(isset($modeInfos[$modename])){
                $modeInfo = $modeInfos[$modename];
                $paymodes[$modename] = ['payname'=>$modeInfo['payname'],'icontype'=>$modeInfo['icon_url']];
            }
        }
        return $paymodes;
    }

    public function transfer($transinfo)
    {
        $data = [
            'trans_no' => $transinfo['id'],
            //'openid' => 'o-e_mwTXTaxEhBM8xDoj1ui1f950',
            'check_name' => 'NO_CHECK',// NO_CHECK：不校验真实姓名  FORCE_CHECK：强校验真实姓名   OPTION_CHECK：针对已实名认证的用户才校验真实姓名
            'payee_real_name' => $transinfo['payeename'],
            'payee_account' => $transinfo['payeeaccount'],
            'amount' => $transinfo['cashnum'],
            'desc' => '提现',
            'payer_show_name' => '致一科技',
            //'spbill_create_ip' => '127.0.0.1',
        ];

        $transferConfig = Db::name('transfermode')->find($transinfo['transfermode']);
        if(empty($transferConfig)||$transferConfig['enable_i']!=1){
             echo 'transferMode closed';
            return false;
        }
        $transfermode = $transferConfig['classname'];
        $cfg = json_decode($transferConfig['transferconfig'],true);

        if(strpos($transfermode,'ali') === 0)
        {
            $data = [
                'trans_no' => $transinfo['id'],
                'payee_type' => 'ALIPAY_LOGONID',
                'payee_account' => $transinfo['payeeaccount'],// ALIPAY_USERID: 2088102169940354      ALIPAY_LOGONID：aaqlmq0729@sandbox.com
                //'amount' => $transinfo['cashnum'],
                'amount' => 0.1,
                'remark' => '提现',
                'payer_show_name' => '致一科技',
                'payee_real_name' => $transinfo['payeename'],
            ];
        }
        else if(strpos($transfermode,'wx') === 0)
        {
            // $data = [
            //     'trans_no' => $transinfo['id'],
            //     //'openid' => 'o-e_mwTXTaxEhBM8xDoj1ui1f950',
            //     'check_name' => 'NO_CHECK',// NO_CHECK：不校验真实姓名  FORCE_CHECK：强校验真实姓名   OPTION_CHECK：针对已实名认证的用户才校验真实姓名
            //     'payer_real_name' => '何磊',
            //     're_user_name' => $transinfo['payeename'],
            //     'amount' => '1',
            //     'desc' => '测试转账',
            //     'spbill_create_ip' => '127.0.0.1',
            // ];
        }

        $re['status'] = 'failed';
        try {
            $ret = Transfer::run($transfermode, $cfg, $data);

            if($ret['is_success'] == 'T'){
                $re['status'] = 'success';
                $re['trans_no'] = $ret['response']['trans_no'];
                $re['transaction_id'] = $ret['response']['transaction_id'];
                $re['pay_date'] = $ret['response']['pay_date'];
            } else {
                // $re['msg'] = $ret->$responseNode->msg;
                // $re['code'] = $resultCode;
            }
            return $re;

        } catch (PayException $e) {
            return $e->errorMessage();
        }
    }
}